package com.hy.node;

public class IntersectionNode {


    /**
     *  02.07. 链表相交
     *  给你两个单链表的头节点 headA 和 headB ，请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点，返回 null 。
     *
     * 图示两个链表在节点 c1 开始相交：
     *  headA       4   1   8   7   5
     *  headB  5    0   1   8   7   5
     *  相交  1
     *  headA 1   headB 2
     *  没有相交 则返回 null
     *
     * 思路
     * 简单来说，就是求两个链表交点节点的指针。 这里同学们要注意，交点不是数值相等，而是指针相等。
     *
     * 为了方便举例，假设节点元素数值相等，则节点指针相等。
     *
     * 看如下两个链表，目前curA指向链表A的头结点，curB指向链表B的头结点：
     *
     * 1. 我们求出两个链表的长度，并求出两个链表长度的差值，然后让curA移动到，和curB 末尾对齐的位置，如图：
     *
     * 2. 此时我们就可以比较curA和curB是否相同，如果不相同，同时向后移动curA和curB，如果遇到curA == curB，则找到交点。
     *
     * 否则循环退出返回空指针。
     */
    // 双指针法
    public static ListNode getIntersectionNode(ListNode headA,ListNode headB){
        ListNode curA = headA;
        ListNode curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != null) { // 求链表A的长度
            lenA++;
            curA = curA.next;
        }
        while (curB != null) { // 求链表B的长度
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头，lenA为其长度   如果链表长度不一致   链表调换顺序
        if (lenB > lenA) {
            //1. swap (lenA, lenB);
            int tmpLen = lenA;
            lenA = lenB;
            lenB = tmpLen;
            //2. swap (curA, curB);
            ListNode tmpNode = curA;
            curA = curB;
            curB = tmpNode;
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上（末尾位置对齐）
        while (gap-- > 0) {
            curA = curA.next;
        }
        // 遍历curA 和 curB，遇到相同则直接返回
        while (curA != null) {
            // curA 与 curB的值相等 的话  有交叉数据
            if (curA.val == curB.val) {
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;
    }

    static class ListNode{
        int val;
        ListNode next;

        public ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }

        @Override
        public String toString() {
            return "ListNode{" +
                    "val=" + val +
                    ", next=" + next +
                    '}';
        }
    }

    public static void main(String[] args) {

        ListNode listNode5 = new ListNode(5,null);
        ListNode listNode4 = new ListNode(4,listNode5);
        ListNode listNode3 = new ListNode(3,listNode4);
        ListNode listNode2 = new ListNode(2,listNode3);
        ListNode headA = new ListNode(1,listNode2);

        ListNode h3 = new ListNode(6,null);
        ListNode h2 = new ListNode(5,h3);
        ListNode h1 = new ListNode(4,h2);
        ListNode h0 = new ListNode(3,h1);
        ListNode headB = new ListNode(1,h0);


        System.out.println(getIntersectionNode(headB,headA));
        
    }
}
